﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FlashCards.Model;

namespace FlashCards.WebApp.Utils
{
    public class GroupUtils
    {
        public static Group GetGroupById(int groupId)
        {
            using (var context = new FlashCardsEntities())
            {
                return context.Groups.FirstOrDefault(x => x.GroupId == groupId);
            }
        }

        public static string GetGroupOwnerNick(int groupId)
        {
            using (var context = new FlashCardsEntities())
            {
                return context.Groups.FirstOrDefault(x => x.GroupId == groupId).Owner.Nick;
            }
        }

        public static List<Group> GetGroupsWhereMember(string userNick)
        {
            using (var context = new FlashCardsEntities())
            {
                var list = new List<Group>();
                var user = context.Users.FirstOrDefault(x => x.Nick == userNick);

                var query = context.Groups.Include("GroupMembers.User").Include("FlashcardSets");

                list = (from g in query
                        where g.GroupMembers.FirstOrDefault(x => x.User.Nick == userNick) != null
                        select g).ToList();

                return list;
            }
        }

        public static void AddNewGroup(string groupName, bool isHidden, string userNick)
        {
            using (var context = new FlashCardsEntities())
            {
                var user = context.Users.SingleOrDefault(x => x.Nick == userNick);

                if (user == null)
                    throw new Exception("User not found.");

                //sprawdzanie czy nie ma juz grupy z taka nazwa
                var group = context.Groups.FirstOrDefault(x => x.Name == groupName);
                if (group != null)
                    throw new Exception("Group with such name already exists.");

                var groupRole = context.GroupRoles.FirstOrDefault(x => x.Name == "Owner");

                var newGroup = new Group { Name = groupName, IsHidden = isHidden, Owner = user };
                var newGroupMember = new GroupMember { User = user, Group = group, GroupRole = groupRole };


                context.Groups.AddObject(newGroup);

                context.SaveChanges();
            }
        }

        public static List<User> GetGroupMembers(int groupId)
        {
            using (var context = new FlashCardsEntities())
            {
                var list = new List<User>();

                list = context.Groups
                    .Where(x => x.GroupId == groupId)
                    .FirstOrDefault()
                    .GroupMembers
                    .Select(x => x.User).ToList();

                return list;
            }
        }

        public static void AddUserToGroup(int groupId, int userId)
        {
            using (var context = new FlashCardsEntities())
            {
                var newGroupMember = new GroupMember();
                newGroupMember.GroupId = groupId;
                newGroupMember.UserId = userId;
                //groupRole = reader user
                newGroupMember.GroupRole = context.GroupRoles.FirstOrDefault(x => x.GroupRoleId == 4);

                context.SaveChanges();

            }
        }

        /// <summary>
        /// Pobiera listę wszystkich zestawów związanych z daną grupą
        /// </summary>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public static List<FlashcardSet> GetGroupFlashcardSets(int groupId)
        {
            using (var context = new FlashCardsEntities())
            {
                var flashcardSets = context.Groups.FirstOrDefault(x => x.GroupId == groupId)
                    .FlashcardSets;

                return flashcardSets.ToList();
            }
        }

        /// <summary>
        /// Pobiera uprawnienia danego użytkownika w obrębie danej grupy
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static string GetUserGroupPrivilege(int userId, int groupId)
        {
            using (var context = new FlashCardsEntities())
            {
                var privilege = context.GroupMembers.FirstOrDefault(x => x.UserId == userId && x.GroupId == groupId)
                    .GroupRole.Name;

                return privilege;
            }
        }

        public static void RemoveUserFromGroup(int userId, int groupId)
        {
            if (userId != 0 && groupId != 0)
            {
                using (var context = new FlashCardsEntities())
                {
                    var userMembership = context.GroupMembers.FirstOrDefault(x => x.UserId == userId && x.GroupId == groupId);
                    if (userMembership != null)
                    {
                        context.GroupMembers.DeleteObject(userMembership);
                        context.SaveChanges();
                    }
                }
            }
            else
                throw new ArgumentNullException("RemoveUserFromGroup");

        }

        /// <summary>
        /// Zwraca role w grupach, które można ustawiać (wszystkie poza Owner)
        /// </summary>
        /// <returns></returns>
        public static List<GroupRole> GetSettableGroupRoles()
        {
            using (var context = new FlashCardsEntities())
            {
                return context.GroupRoles.Where(x => x.Name != "Owner").ToList();
            }
        }

        public static void SetUserGroupRole(int userId, int groupId, string roleName)
        {
            using (var context = new FlashCardsEntities())
            {
                var groupRole = context.GroupRoles.FirstOrDefault(x => x.Name == roleName);

                var membership = context.GroupMembers.FirstOrDefault(x => x.UserId == userId && x.GroupId == groupId);
                membership.GroupRoleId = groupRole.GroupRoleId;
                context.SaveChanges();
            }
        }

        public static void AddExistingSetToGroup(int groupId, int setId)
        {
            using (var context = new FlashCardsEntities())
            {
                var set = context.FlashcardSets.FirstOrDefault(x => x.FlashcardSetId == setId);
                set.GroupId = groupId;

                context.SaveChanges();
            }
        }

        public static void RemoveSetFromGroup(int setId)
        {
            using (var context = new FlashCardsEntities())
            {
                var set = context.FlashcardSets.FirstOrDefault(x => x.FlashcardSetId == setId);
                set.GroupId = null;

                context.SaveChanges();
            }
        }
    }
}